#ifndef lint
static const char yysccsid[] = "@(#)yaccpar	1.9 (Berkeley) 02/21/93";
#endif

#define YYBYACC 1
#define YYMAJOR 1
#define YYMINOR 9
#define YYPATCH 20100610

#define YYEMPTY        (-1)
#define yyclearin      (yychar = YYEMPTY)
#define yyerrok        (yyerrflag = 0)
#define YYRECOVERING() (yyerrflag != 0)

#define YYPREFIX "yy"

#define YYPURE 0

#line 12 "pico.y"
  /* Aqui, pode-se inserir qualquer codigo C necessario ah compilacao
   * final do parser. Sera copiado tal como esta no inicio do y.tab.c
   * gerado por Yacc.
   */
  #include <stdio.h>
  #include <stdlib.h>
  #include "symbol_table.h"
  #include "lista.h"
  #include "node.h"



char* lexema;
symbol_t symbol_table;
int deslocamento=0;

#line 30 "pico.y"
typedef union {
  char* cadeia;
  struct _node * no;
} YYSTYPE;
#line 41 "y.tab.c"
/* compatibility with bison */
#ifdef YYPARSE_PARAM
/* compatibility with FreeBSD */
# ifdef YYPARSE_PARAM_TYPE
#  define YYPARSE_DECL() yyparse(YYPARSE_PARAM_TYPE YYPARSE_PARAM)
# else
#  define YYPARSE_DECL() yyparse(void *YYPARSE_PARAM)
# endif
#else
# define YYPARSE_DECL() yyparse(void)
#endif

/* Parameters sent to lex. */
#ifdef YYLEX_PARAM
# define YYLEX_DECL() yylex(void *YYLEX_PARAM)
# define YYLEX yylex(YYLEX_PARAM)
#else
# define YYLEX_DECL() yylex(void)
# define YYLEX yylex()
#endif

extern int YYPARSE_DECL();
extern int YYLEX_DECL();

#define IPRINT 257
#define REAL 258
#define FOR 259
#define NEXT 260
#define REPEAT 261
#define UNTIL 262
#define CONST 263
#define CASE 264
#define INT 265
#define DOUBLE 266
#define CHAR 267
#define QUOTE 268
#define DQUOTE 269
#define LE 270
#define GE 271
#define EQ 272
#define NE 273
#define AND 274
#define OR 275
#define NOT 276
#define IF 277
#define THEN 278
#define ELSE 279
#define WHILE 280
#define END 281
#define TRUE 282
#define FALSE 283
#define INT_LIT 284
#define F_LIT 285
#define IDF 286
#define YYERRCODE 256
static const short yylhs[] = {                           -1,
    0,    0,    6,    6,    7,    8,    8,    9,    9,   10,
   10,   10,   10,   11,   11,   11,   11,   12,   12,    1,
    1,    2,    2,    5,    5,   13,   13,    4,    4,    4,
    4,    4,    4,    4,    4,    4,   14,    3,    3,    3,
    3,   15,   15,   16,   16,   16,   16,   16,   16,   16,
   16,   16,   16,   16,   16,
};
static const short yylen[] = {                            2,
    2,    1,    2,    3,    3,    1,    3,    1,    1,    1,
    1,    1,    1,    4,    4,    4,    4,    3,    5,    2,
    3,    3,    1,    1,    4,    1,    3,    3,    3,    3,
    3,    3,    1,    1,    1,    1,    4,    1,    7,    7,
    4,    1,    3,    1,    1,    3,    3,    3,    2,    3,
    3,    3,    3,    3,    3,
};
static const short yydefred[] = {                         0,
    0,    0,    0,   33,   34,    0,    0,    0,    2,    0,
   23,    0,    0,    0,    0,    0,   36,    0,    0,    0,
    0,    0,    0,    0,    0,   35,    0,    0,    0,    0,
    0,    0,    1,    0,    3,    0,    0,    0,   44,   45,
    0,    0,    0,    0,    0,    7,    0,    0,    0,   32,
   21,    0,    0,   30,   31,    0,    4,    0,    0,    0,
    0,    5,    8,    9,   41,   49,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,   25,
   37,    0,    0,    0,    0,   46,    0,    0,    0,    0,
    0,    0,   47,    0,    0,    0,   27,    0,    0,    0,
    0,    0,    0,    0,    0,   16,   14,   15,   17,    0,
   42,   39,   40,    0,    0,    0,   43,   19,
};
static const short yydgoto[] = {                          8,
    9,   10,   11,   12,   26,   14,   15,   16,   62,   63,
   64,   99,   48,   17,  112,   43,
};
static const short yysindex[] = {                       -40,
  -33,  -27,  -26,    0,    0,  -18,  -28,    0,    0,  -51,
    0,  144,  -38,  -40,  -30,  -17,    0,  -28,  -35,  -35,
 -262,  -28,  -28,  -34,  122,    0,  -25,  -28,  -28,  -28,
  -28,  -28,    0,   -4,    0, -190,  129,  -35,    0,    0,
  -35,   48,  -39,  -32,  -16,    0,  111,  -66,  -10,    0,
    0,  -31,  -31,    0,    0,  144,    0,  -59,  -45,  -19,
   -2,    0,    0,    0,    0,    0,   41,  -21,  -28,  -28,
  -28,  -28,  -28,  -28,  -35,  -35, -222,  -49,  -28,    0,
    0, -197, -197, -197, -197,    0,  144,  144,  144,  144,
  144,  144,    0, -180,  -25,  -25,    0,   39,    7,   12,
   16,   18, -260,   -7, -182,    0,    0,    0,    0,  -25,
    0,    0,    0,   60, -166, -197,    0,    0,
};
static const short yyrindex[] = {                         0,
    0,    0,    0,    0,    0,  101,    0,    0,    0,    0,
    0,   64,   77,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,   -8,    0,    0,    1,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,   67,    0,  -23,    0,    0,    0,
    0,   -1,   19,    0,    0,   71,    0,   74,   75,   83,
   86,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    4,    9,   24,   26,
   28,   30,    0,  -37,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,   42,    0,    0,    0,    0,
};
static const short yygindex[] = {                         0,
   11,    0,    0,  109,    3,    0,  135,  136,    0,    0,
    0,  -36,  -13,    0,    0,   76,
};
#define YYTABLESIZE 321
static const short yytable[] = {                          7,
   20,   77,   13,   48,   41,   23,   18,   27,   78,   49,
   30,    7,   19,   20,    7,   31,   13,   26,  110,   86,
  111,   23,   32,   45,   33,   21,   80,   21,   35,   13,
   81,   82,   24,   24,   24,   24,   24,   51,   24,   28,
   36,   28,   28,   28,   52,   83,  100,  101,  102,   53,
   24,   24,   24,   24,   57,   95,   22,   28,   28,   29,
   28,   29,   29,   29,   54,   97,   55,   58,   50,   26,
   51,   84,   22,   96,   59,   60,   61,   29,   29,  118,
   29,   50,   30,   28,   24,   29,   98,   31,   85,   30,
   28,   28,   29,   75,   31,   44,  105,   13,   13,  106,
   74,  114,   73,  116,  107,  103,  104,   74,  108,   73,
  109,   29,   13,   66,  117,   25,   68,  113,   35,   35,
  115,   35,   38,   35,    6,   20,   37,   42,   42,   22,
   47,   47,   12,   10,   18,   35,   52,   53,   54,   55,
   56,   11,   24,   24,   13,   24,   42,   24,   34,   67,
   93,   94,   30,   28,   79,   29,   46,   31,    6,   24,
    0,   24,   50,   30,   28,    0,   29,    0,   31,   65,
   30,   28,    0,   29,    0,   31,    0,   87,   88,   89,
   90,   91,   92,   42,   42,   30,   28,   47,   29,    0,
   31,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    1,    0,    0,    0,
    0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
    0,    1,    0,    0,   75,   76,    2,   48,    0,    3,
   38,   75,   76,    4,    5,    6,   39,   40,    4,    5,
   24,    2,   75,   76,    3,    4,    5,   24,    4,    5,
   24,   24,   24,   24,   24,   24,   24,    0,   28,   28,
   28,   28,   28,   28,    0,    0,    0,   52,   52,   20,
    0,   20,   53,   53,    0,    0,    0,    0,   29,   29,
   29,   29,   29,   29,    0,    0,    0,   54,   54,   55,
   55,   50,   50,   51,   51,    0,    0,    0,    0,    0,
   69,   70,   71,   72,    0,    0,    0,   69,   70,   71,
   72,
};
static const short yycheck[] = {                         40,
    0,   41,    0,   41,   40,   40,   40,   59,   41,   23,
   42,   40,   40,   40,   40,   47,   14,   41,  279,   41,
  281,   40,   61,  286,   14,   44,   93,   44,   59,   27,
   41,   91,   41,   42,   43,   44,   45,   27,   47,   41,
   58,   43,   44,   45,   41,   91,   83,   84,   85,   41,
   59,   60,   61,   62,   59,  278,   91,   59,   60,   41,
   62,   43,   44,   45,   41,   79,   41,  258,   41,   93,
   41,   91,   91,  123,  265,  266,  267,   59,   60,  116,
   62,   41,   42,   43,   93,   45,  284,   47,   91,   42,
   43,   93,   45,  274,   47,   20,   58,   95,   96,   93,
   60,  284,   62,   44,   93,   95,   96,   60,   93,   62,
   93,   93,  110,   38,  281,    7,   41,  125,   42,   43,
  110,   45,   59,   47,   58,  125,   18,   19,   20,   59,
   22,   23,   59,   59,   93,   59,   28,   29,   30,   31,
   32,   59,   42,   43,   59,   45,   38,   47,   14,   41,
   75,   76,   42,   43,   44,   45,   21,   47,   58,   59,
   -1,   61,   41,   42,   43,   -1,   45,   -1,   47,   41,
   42,   43,   -1,   45,   -1,   47,   -1,   69,   70,   71,
   72,   73,   74,   75,   76,   42,   43,   79,   45,   -1,
   47,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,  257,   -1,   -1,   -1,
   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,   -1,
   -1,  257,   -1,   -1,  274,  275,  277,  275,   -1,  280,
  276,  274,  275,  284,  285,  286,  282,  283,  284,  285,
  286,  277,  274,  275,  280,  284,  285,  286,  284,  285,
  286,  270,  271,  272,  273,  274,  275,   -1,  270,  271,
  272,  273,  274,  275,   -1,   -1,   -1,  274,  275,  279,
   -1,  281,  274,  275,   -1,   -1,   -1,   -1,  270,  271,
  272,  273,  274,  275,   -1,   -1,   -1,  274,  275,  274,
  275,  274,  275,  274,  275,   -1,   -1,   -1,   -1,   -1,
  270,  271,  272,  273,   -1,   -1,   -1,  270,  271,  272,
  273,
};
#define YYFINAL 8
#ifndef YYDEBUG
#define YYDEBUG 0
#endif
#define YYMAXTOKEN 286
#if YYDEBUG
static const char *yyname[] = {

"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,"'('","')'","'*'","'+'","','","'-'",0,"'/'",0,0,0,0,0,0,0,0,0,0,
"':'","';'","'<'","'='","'>'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,"'['",0,"']'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
"'{'",0,"'}'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"IPRINT","REAL","FOR","NEXT","REPEAT",
"UNTIL","CONST","CASE","INT","DOUBLE","CHAR","QUOTE","DQUOTE","LE","GE","EQ",
"NE","AND","OR","NOT","IF","THEN","ELSE","WHILE","END","TRUE","FALSE","INT_LIT",
"F_LIT","IDF",
};
static const char *yyrule[] = {
"$accept : code",
"code : declaracoes acoes",
"code : acoes",
"declaracoes : declaracao ';'",
"declaracoes : declaracoes declaracao ';'",
"declaracao : listadeclaracao ':' tipo",
"listadeclaracao : IDF",
"listadeclaracao : IDF ',' listadeclaracao",
"tipo : tipounico",
"tipo : tipolista",
"tipounico : INT",
"tipounico : DOUBLE",
"tipounico : REAL",
"tipounico : CHAR",
"tipolista : INT '[' listadupla ']'",
"tipolista : DOUBLE '[' listadupla ']'",
"tipolista : REAL '[' listadupla ']'",
"tipolista : CHAR '[' listadupla ']'",
"listadupla : INT_LIT ':' INT_LIT",
"listadupla : INT_LIT ':' INT_LIT ',' listadupla",
"acoes : comando ';'",
"acoes : comando ';' acoes",
"comando : lvalue '=' expr",
"comando : enunciado",
"lvalue : IDF",
"lvalue : IDF '[' listaexpr ']'",
"listaexpr : expr",
"listaexpr : expr ',' listaexpr",
"expr : expr '+' expr",
"expr : expr '-' expr",
"expr : expr '*' expr",
"expr : expr '/' expr",
"expr : '(' expr ')'",
"expr : INT_LIT",
"expr : F_LIT",
"expr : lvalue",
"expr : chamaproc",
"chamaproc : IDF '(' listaexpr ')'",
"enunciado : expr",
"enunciado : IF '(' expbool ')' THEN acoes fiminstcontrole",
"enunciado : WHILE '(' expbool ')' '{' acoes '}'",
"enunciado : IPRINT '(' expr ')'",
"fiminstcontrole : END",
"fiminstcontrole : ELSE acoes END",
"expbool : TRUE",
"expbool : FALSE",
"expbool : '(' expbool ')'",
"expbool : expbool AND expbool",
"expbool : expbool OR expbool",
"expbool : NOT expbool",
"expbool : expr '>' expr",
"expbool : expr '<' expr",
"expbool : expr LE expr",
"expbool : expr GE expr",
"expbool : expr EQ expr",
"expbool : expr NE expr",

};
#endif
/* define the initial stack-sizes */
#ifdef YYSTACKSIZE
#undef YYMAXDEPTH
#define YYMAXDEPTH  YYSTACKSIZE
#else
#ifdef YYMAXDEPTH
#define YYSTACKSIZE YYMAXDEPTH
#else
#define YYSTACKSIZE 500
#define YYMAXDEPTH  500
#endif
#endif

#define YYINITSTACKSIZE 500

int      yydebug;
int      yynerrs;

typedef struct {
    unsigned stacksize;
    short    *s_base;
    short    *s_mark;
    short    *s_last;
    YYSTYPE  *l_base;
    YYSTYPE  *l_mark;
} YYSTACKDATA;
int      yyerrflag;
int      yychar;
YYSTYPE  yyval;
YYSTYPE  yylval;

/* variables for the parser stack */
static YYSTACKDATA yystack;
#line 906 "pico.y"
 /* A partir daqui, insere-se qualqer codigo C necessario.
  */

char* progname;
int lineno;
extern FILE* yyin;

FILE* saida;


void gen_attributes_exbool(Node* n)
{ 
    if(n->type==true_node)
    {
        struct node_tac*  nodetac=NULL;
        struct tac*  new_tac = NULL;

        new_tac=create_inst_tac(TAC_GOTO,"", n->attribute->t,"", "");

        append_inst_tac(&nodetac, new_tac); 
                        
        n->attribute->code=nodetac;
   
    }
    if(n->type==false_node)
    {
        struct node_tac*  nodetac=NULL;
        struct tac*  new_tac = NULL;

        new_tac=create_inst_tac(TAC_GOTO,"", n->attribute->f,"", "");

        append_inst_tac(&nodetac, new_tac); 
   
        n->attribute->code=nodetac;
  
    }
    if(n->type==assexpbool_node)
    {
        // aqui estah invertido em relaçao aos slides, atributos são herdados, ao invés de sintetizados
        n->children[1]->attribute->t=n->attribute->t;
        n->children[1]->attribute->f=n->attribute->f;

        gen_attributes_exbool(n->children[1]);

        // jah code eh sintetizado como estah nos slides
        n->attribute->code=n->children[1]->attribute->code;        

    }
    if(n->type==not_node)
    {
        n->children[1]->attribute->t=n->attribute->f;
        n->children[1]->attribute->f=n->attribute->t;

        gen_attributes_exbool(n->children[1]);

        n->attribute->code=n->children[1]->attribute->code;        
    }
    if(n->type==and_node)
    {
        n->children[0]->attribute->t=novo_rot(malloc(sizeof(char)*(10)));
        n->children[0]->attribute->f=n->attribute->f;

        n->children[2]->attribute->t=n->attribute->t;
        n->children[2]->attribute->f=n->attribute->f;

        gen_attributes_exbool(n->children[0]);
        gen_attributes_exbool(n->children[2]);

        //B.code = B1.code || label(B1.t) || B2.code
        n->attribute->code=n->children[0]->attribute->code;        

        struct tac*  new_tac = create_inst_tac(TAC_LABEL,"", n->children[0]->attribute->t,"", "");

        append_inst_tac(&n->attribute->code, new_tac); 
   
        cat_tac(&n->attribute->code, &n->children[2]->attribute->code);
    }
    if(n->type==or_node)
    {
        n->children[0]->attribute->t=n->attribute->t;
        n->children[0]->attribute->f=novo_rot(malloc(sizeof(char)*(10)));

        n->children[2]->attribute->t=n->attribute->t;
        n->children[2]->attribute->f=n->attribute->f;

        gen_attributes_exbool(n->children[0]);
        gen_attributes_exbool(n->children[2]);

        //B.code = B1.code || label(B1.t) || B2.code
        n->attribute->code=n->children[0]->attribute->code;        

        struct tac*  new_tac = create_inst_tac(TAC_LABEL,"", n->children[0]->attribute->f,"", "");

        append_inst_tac(&n->attribute->code, new_tac); 
   
        cat_tac(&n->attribute->code, &n->children[2]->attribute->code);
    }
    if(n->type==relop_node)
    {
        //B.code = E1.code ||
        n->attribute->code=n->children[0]->attribute->code;        

        //E2.code ||
        cat_tac(&n->attribute->code, &n->children[2]->attribute->code);
        
        //gera_cod(“if” E1.local relop.lexval E2.local “goto” B.t) ||
        struct tac*  new_tac1 =create_inst_tac(TAC_IF,n->attribute->t, n->children[0]->attribute->local,n->children[1]->lexeme, n->children[2]->attribute->local);
        append_inst_tac(&n->attribute->code, new_tac1);
                        
        //gera_cod(“goto” B.f)
        struct tac*  new_tac2 = create_inst_tac(TAC_GOTO,"", n->attribute->f,"", "");
        append_inst_tac(&n->attribute->code, new_tac2);
    
    }
}
void insert_table(Node* n, Node* type)
{
    //printf("type: %d\n",n->type);
    if(n->type==idf_node)
    {
        entry_t* entrada = malloc(sizeof(entry_t));
        //entrada->name = malloc(sizeof(char)*(strlen(n->lexeme) + 1));
        //strcpy(entrada->name, n->lexeme);
        entrada->name = n->lexeme;
        
        if(type->type==int_kw_node)
        {
            entrada->type =TYPE_INT;
            entrada->size =TAM_INT;
            entrada->extra=NULL;
        }
        else if(type->type==real_kw_node)
        {
            entrada->type =TYPE_REAL;
            entrada->size =TAM_REAL;
            entrada->extra=NULL;
        }
        else if(type->type==double_kw_node)
        {
            entrada->type =TYPE_DOUBLE;
            entrada->size =TAM_DOUBLE;
            entrada->extra=NULL;
        }
        else if(type->type==char_kw_node)
        {
            entrada->type =TYPE_CHAR;
            entrada->size =TAM_CHAR;
            entrada->extra=NULL;
        }
        else if(type->type==tipo_list_node)
        {   //(7 *8)+(1*4)+(2 *1)-5*8 -0*4 -1*1= 16+4+1=21
            int tam=1;
            int offset=0;
            struct array_info* arr = type->attribute->array;
            while(arr!=NULL)
            {
                offset=offset+tam*arr->start;
                arr->off=tam;
                tam*=arr->tam;
                arr=arr->next;
            }

            if(type->children[0]->type==int_kw_node)
            {
                entrada->type =TYPE_INT;
                entrada->size =TAM_INT * tam;
            }
            else if(type->children[0]->type==real_kw_node)
            {
                entrada->type =TYPE_REAL;
                entrada->size =TAM_REAL * tam;
                entrada->extra=NULL;
            }
            else if(type->children[0]->type==double_kw_node)
            {
                entrada->type =TYPE_DOUBLE;
                entrada->size =TAM_DOUBLE * tam;
                entrada->extra=NULL;
            }
            else if(type->children[0]->type==char_kw_node)
            {
                entrada->type =TYPE_CHAR;
                entrada->size =TAM_CHAR * tam;
                entrada->extra=NULL;
            }
            type->attribute->array->offset=offset;        
            entrada->extra=type->attribute->array;
        }
        
        entrada->desloc = deslocamento;
        deslocamento+=entrada->size;
        insert(&symbol_table, entrada);
    }
    else if(n->type==decl_list_node)
    {
        insert_table(n->children[0],type);
        insert_table(n->children[2],type);
    }


 
}

int get_deslocamento()
{
    return deslocamento;
}

int main(int argc, char* argv[]) 
{

   init_table(&symbol_table);

   if (argc != 2) {
     printf("uso: %s <input_file>. Try again!\n", argv[0]);
     exit(-1);
   }
   yyin = fopen(argv[1], "r");
   if (!yyin) {
     printf("Uso: %s <input_file>. Could not find %s. Try again!\n", 
         argv[0], argv[1]);
     exit(-1);
   }

   progname = argv[0];

   if (!yyparse()) 
   {
      printf("OKAY.\n"); 
      print_tree(syntax_tree,0); /* se o parser aceita a entrada então imprime a árvore a partir do nó raiz */
      
      
      
      
      saida = fopen("code.pico", "w");
        
        if(syntax_tree->attribute!=NULL) 
            print_tac(saida, syntax_tree->attribute->code);
 
        print_table(symbol_table);
  
      deep_free_node(syntax_tree) ;
      free_table(&symbol_table);      
   }
   else 
      printf("ERROR.\n");

   return(0);
}

yyerror(char* s) {
  fprintf(stderr, "%s: %s", progname, s);
  fprintf(stderr, "line %d\n", lineno);
}
#line 602 "y.tab.c"

#if YYDEBUG
#include <stdio.h>		/* needed for printf */
#endif

#include <stdlib.h>	/* needed for malloc, etc */
#include <string.h>	/* needed for memset */

/* allocate initial stack or double stack size, up to YYMAXDEPTH */
static int yygrowstack(YYSTACKDATA *data)
{
    int i;
    unsigned newsize;
    short *newss;
    YYSTYPE *newvs;

    if ((newsize = data->stacksize) == 0)
        newsize = YYINITSTACKSIZE;
    else if (newsize >= YYMAXDEPTH)
        return -1;
    else if ((newsize *= 2) > YYMAXDEPTH)
        newsize = YYMAXDEPTH;

    i = data->s_mark - data->s_base;
    newss = (data->s_base != 0)
          ? (short *)realloc(data->s_base, newsize * sizeof(*newss))
          : (short *)malloc(newsize * sizeof(*newss));
    if (newss == 0)
        return -1;

    data->s_base = newss;
    data->s_mark = newss + i;

    newvs = (data->l_base != 0)
          ? (YYSTYPE *)realloc(data->l_base, newsize * sizeof(*newvs))
          : (YYSTYPE *)malloc(newsize * sizeof(*newvs));
    if (newvs == 0)
        return -1;

    data->l_base = newvs;
    data->l_mark = newvs + i;

    data->stacksize = newsize;
    data->s_last = data->s_base + newsize - 1;
    return 0;
}

#if YYPURE || defined(YY_NO_LEAKS)
static void yyfreestack(YYSTACKDATA *data)
{
    free(data->s_base);
    free(data->l_base);
    memset(data, 0, sizeof(*data));
}
#else
#define yyfreestack(data) /* nothing */
#endif

#define YYABORT  goto yyabort
#define YYREJECT goto yyabort
#define YYACCEPT goto yyaccept
#define YYERROR  goto yyerrlab

int
YYPARSE_DECL()
{
    int yym, yyn, yystate;
#if YYDEBUG
    const char *yys;

    if ((yys = getenv("YYDEBUG")) != 0)
    {
        yyn = *yys;
        if (yyn >= '0' && yyn <= '9')
            yydebug = yyn - '0';
    }
#endif

    yynerrs = 0;
    yyerrflag = 0;
    yychar = YYEMPTY;
    yystate = 0;

#if YYPURE
    memset(&yystack, 0, sizeof(yystack));
#endif

    if (yystack.s_base == NULL && yygrowstack(&yystack)) goto yyoverflow;
    yystack.s_mark = yystack.s_base;
    yystack.l_mark = yystack.l_base;
    yystate = 0;
    *yystack.s_mark = 0;

yyloop:
    if ((yyn = yydefred[yystate]) != 0) goto yyreduce;
    if (yychar < 0)
    {
        if ((yychar = YYLEX) < 0) yychar = 0;
#if YYDEBUG
        if (yydebug)
        {
            yys = 0;
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
            if (!yys) yys = "illegal-symbol";
            printf("%sdebug: state %d, reading %d (%s)\n",
                    YYPREFIX, yystate, yychar, yys);
        }
#endif
    }
    if ((yyn = yysindex[yystate]) && (yyn += yychar) >= 0 &&
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
    {
#if YYDEBUG
        if (yydebug)
            printf("%sdebug: state %d, shifting to state %d\n",
                    YYPREFIX, yystate, yytable[yyn]);
#endif
        if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack))
        {
            goto yyoverflow;
        }
        yystate = yytable[yyn];
        *++yystack.s_mark = yytable[yyn];
        *++yystack.l_mark = yylval;
        yychar = YYEMPTY;
        if (yyerrflag > 0)  --yyerrflag;
        goto yyloop;
    }
    if ((yyn = yyrindex[yystate]) && (yyn += yychar) >= 0 &&
            yyn <= YYTABLESIZE && yycheck[yyn] == yychar)
    {
        yyn = yytable[yyn];
        goto yyreduce;
    }
    if (yyerrflag) goto yyinrecovery;

    yyerror("syntax error");

    goto yyerrlab;

yyerrlab:
    ++yynerrs;

yyinrecovery:
    if (yyerrflag < 3)
    {
        yyerrflag = 3;
        for (;;)
        {
            if ((yyn = yysindex[*yystack.s_mark]) && (yyn += YYERRCODE) >= 0 &&
                    yyn <= YYTABLESIZE && yycheck[yyn] == YYERRCODE)
            {
#if YYDEBUG
                if (yydebug)
                    printf("%sdebug: state %d, error recovery shifting\
 to state %d\n", YYPREFIX, *yystack.s_mark, yytable[yyn]);
#endif
                if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack))
                {
                    goto yyoverflow;
                }
                yystate = yytable[yyn];
                *++yystack.s_mark = yytable[yyn];
                *++yystack.l_mark = yylval;
                goto yyloop;
            }
            else
            {
#if YYDEBUG
                if (yydebug)
                    printf("%sdebug: error recovery discarding state %d\n",
                            YYPREFIX, *yystack.s_mark);
#endif
                if (yystack.s_mark <= yystack.s_base) goto yyabort;
                --yystack.s_mark;
                --yystack.l_mark;
            }
        }
    }
    else
    {
        if (yychar == 0) goto yyabort;
#if YYDEBUG
        if (yydebug)
        {
            yys = 0;
            if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
            if (!yys) yys = "illegal-symbol";
            printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
                    YYPREFIX, yystate, yychar, yys);
        }
#endif
        yychar = YYEMPTY;
        goto yyloop;
    }

yyreduce:
#if YYDEBUG
    if (yydebug)
        printf("%sdebug: state %d, reducing by rule %d (%s)\n",
                YYPREFIX, yystate, yyn, yyrule[yyn]);
#endif
    yym = yylen[yyn];
    if (yym)
        yyval = yystack.l_mark[1-yym];
    else
        memset(&yyval, 0, sizeof yyval);
    switch (yyn)
    {
case 1:
#line 99 "pico.y"
	{
                Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                children[0]=yystack.l_mark[-1].no;
                children[1]=yystack.l_mark[0].no;
                yyval.no=create_node(0, program_node, "__code", yystack.l_mark[0].no->attribute, 2, children);
                syntax_tree = yyval.no;
            }
break;
case 2:
#line 106 "pico.y"
	{ yyval.no = yystack.l_mark[0].no; syntax_tree = yyval.no;}
break;
case 3:
#line 110 "pico.y"
	{ 
                Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                children[0]=yystack.l_mark[-1].no;
                children[1]=create_leaf(0, ';', ";", NULL);
                yyval.no=create_node(0, decl_node, "__declaracoes", NULL, 2, children);
            }
break;
case 4:
#line 117 "pico.y"
	{
                Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                children[0]=yystack.l_mark[-2].no;
                children[1]=yystack.l_mark[-1].no;
                children[2]=create_leaf(0, ';', ";", NULL);
                yyval.no=create_node(0, decl_node, "__declaracoes", NULL, 3, children);
            }
break;
case 5:
#line 126 "pico.y"
	{
                insert_table(yystack.l_mark[-2].no,yystack.l_mark[0].no);
                
                Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                children[0]=yystack.l_mark[-2].no;
                children[1]=create_leaf(0, ':', ":", NULL);
                children[2]=yystack.l_mark[0].no;
                yyval.no=create_node(0, decl_node, "__declaracao", NULL, 3, children);
            }
break;
case 6:
#line 137 "pico.y"
	{ yyval.no = create_leaf(0, idf_node, yystack.l_mark[0].cadeia, NULL); }
break;
case 7:
#line 139 "pico.y"
	{
                Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                children[0]=create_leaf(0, idf_node, yystack.l_mark[-2].cadeia, NULL);
                children[1]=create_leaf(0, ',', ",", NULL);
                children[2]=yystack.l_mark[0].no;
                yyval.no=create_node(0, decl_list_node, "__listadeclaracao", NULL, 3, children);
            }
break;
case 8:
#line 148 "pico.y"
	{ yyval.no = yystack.l_mark[0].no;}
break;
case 9:
#line 149 "pico.y"
	{ yyval.no = yystack.l_mark[0].no;}
break;
case 10:
#line 152 "pico.y"
	{yyval.no=create_leaf(0, int_kw_node, "int", NULL);}
break;
case 11:
#line 153 "pico.y"
	{yyval.no=create_leaf(0, double_kw_node, "double", NULL);}
break;
case 12:
#line 154 "pico.y"
	{yyval.no=create_leaf(0, real_kw_node, "float", NULL);}
break;
case 13:
#line 155 "pico.y"
	{yyval.no=create_leaf(0, char_kw_node, "char", NULL);}
break;
case 14:
#line 159 "pico.y"
	{
                Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                children[0]=create_leaf(0, int_kw_node, "int", NULL);
                children[1]=create_leaf(0, '[', "[", NULL);
                children[2]=yystack.l_mark[-1].no;
                children[3]=create_leaf(0, ']', "]", NULL);
                yyval.no=create_node(0,tipo_list_node, "__tipolista", yystack.l_mark[-1].no->attribute, 4, children);
            }
break;
case 15:
#line 168 "pico.y"
	{
                Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                children[0]=create_leaf(0, double_kw_node, "double", NULL);
                children[1]=create_leaf(0, '[', "[", NULL);
                children[2]=yystack.l_mark[-1].no;
                children[3]=create_leaf(0, ']', "]", NULL);
                yyval.no=create_node(0,tipo_list_node, "__tipolista", yystack.l_mark[-1].no->attribute, 4, children);
            }
break;
case 16:
#line 177 "pico.y"
	{
                Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                children[0]=create_leaf(0, real_kw_node, "real", NULL);
                children[1]=create_leaf(0, '[', "[", NULL);
                children[2]=yystack.l_mark[-1].no;
                children[3]=create_leaf(0, ']', "]", NULL);
                yyval.no=create_node(0,tipo_list_node, "__tipolista", yystack.l_mark[-1].no->attribute, 4, children);
            }
break;
case 17:
#line 186 "pico.y"
	{
                Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                children[0]=create_leaf(0, char_kw_node, "char", NULL);
                children[1]=create_leaf(0, '[', "[", NULL);
                children[2]=yystack.l_mark[-1].no;
                children[3]=create_leaf(0, ']', "]", NULL);
                yyval.no=create_node(0,tipo_list_node, "__tipolista", yystack.l_mark[-1].no->attribute, 4, children);
            }
break;
case 18:
#line 197 "pico.y"
	{
                Attr*  attribute = (Attr*) malloc(sizeof(Attr));
                attribute->array=(struct array_info*)malloc(sizeof(struct array_info));
                
                attribute->array->start=atoi(yystack.l_mark[-2].cadeia);
                attribute->array->end=atoi(yystack.l_mark[0].cadeia);
                attribute->array->tam=attribute->array->end - attribute->array->start+1;
                attribute->array->next=NULL;
                
                Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                children[0]=create_leaf(0, int_node, yystack.l_mark[-2].cadeia, NULL);
                children[1]=create_leaf(0, ':', ":", NULL);
                children[2]=create_leaf(0, int_node, yystack.l_mark[0].cadeia, NULL);
                yyval.no=create_node(0,listdupla_node, "__listadupla", attribute, 3, children);
                
               
            }
break;
case 19:
#line 215 "pico.y"
	{
                Attr*  attribute = (Attr*) malloc(sizeof(Attr));
                attribute->array=(struct array_info*)malloc(sizeof(struct array_info));
                
                attribute->array->start=atoi(yystack.l_mark[-4].cadeia);
                attribute->array->end=atoi(yystack.l_mark[-2].cadeia);
                attribute->array->tam=attribute->array->end - attribute->array->start+1;
                attribute->array->next=yystack.l_mark[0].no->attribute->array;

                Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                children[0]=create_leaf(0, int_node, yystack.l_mark[-4].cadeia, NULL);
                children[1]=create_leaf(0, ':', ":", NULL);
                                children[2]=create_leaf(0, int_node, yystack.l_mark[-2].cadeia, NULL);
                children[3]=create_leaf(0, ',', ",", NULL);
                children[4]=yystack.l_mark[0].no;
                yyval.no=create_node(0,listdupla_node, "__listadupla", attribute, 5, children);
            }
break;
case 20:
#line 235 "pico.y"
	{
                Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                children[0]=yystack.l_mark[-1].no;
                children[1]=create_leaf(0, ';', ";", NULL);
                yyval.no=create_node(0, acoes_node, "__acoes", yystack.l_mark[-1].no->attribute, 2, children);
                
                
            }
break;
case 21:
#line 244 "pico.y"
	{
                Attr*  attribute = (Attr*) malloc(sizeof(Attr));
                attribute->code=yystack.l_mark[-2].no->attribute->code;

                cat_tac(&attribute->code, &yystack.l_mark[0].no->attribute->code);
 
                Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                children[0]=yystack.l_mark[-2].no;
                children[1]=create_leaf(0, ';', ";", NULL);
                children[2]=yystack.l_mark[0].no;
                yyval.no=create_node(0, acoes_node, "__acoes", attribute, 3, children);
            }
break;
case 22:
#line 259 "pico.y"
	{

                if(yystack.l_mark[-2].no->attribute->type==TYPE_INT && (yystack.l_mark[0].no->attribute->type==TYPE_REAL || yystack.l_mark[0].no->attribute->type==TYPE_DOUBLE))
                {
                    yyerror("Incompatibilidade de tipos.");
                    exit(-1);                
                }
                if(yystack.l_mark[-2].no->attribute->type!=yystack.l_mark[0].no->attribute->type && (yystack.l_mark[-2].no->attribute->type==TYPE_CHAR || yystack.l_mark[0].no->attribute->type==TYPE_CHAR))
                {
                    yyerror("Incompatibilidade de tipos.");
                    exit(-1);                
                }


            
                Attr*  attribute = (Attr*) malloc(sizeof(Attr));
                
                attribute->code=yystack.l_mark[-2].no->attribute->code;
                cat_tac(&attribute->code, &yystack.l_mark[0].no->attribute->code);
                
                struct tac*  new_tac = create_inst_tac(TAC_EXPR, yystack.l_mark[-2].no->attribute->local, yystack.l_mark[0].no->attribute->local,"","");

                append_inst_tac(&attribute->code, new_tac); 
                                            
                Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                children[0]=yystack.l_mark[-2].no;
                children[1]=create_leaf(0, '=', ":=", NULL);
                children[2]=yystack.l_mark[0].no;
                yyval.no=create_node(0, lvalue_node, "__comando", attribute, 3, children);
            }
break;
case 23:
#line 289 "pico.y"
	{ yyval.no = yystack.l_mark[0].no;}
break;
case 24:
#line 293 "pico.y"
	{ 
                entry_t* p = lookup(symbol_table, yystack.l_mark[0].cadeia) ;
                if(p==NULL)
                {
                    yyerror("Identificador invalido var.");
                    exit(-1);
                }
                
                Attr*  attribute = (Attr*) malloc(sizeof(Attr));
                char* desloc = malloc(sizeof(char)*(10));

	            if(p->desloc<10)
	                sprintf(desloc,"00%d(SP)",p->desloc);
	            else if(p->desloc<100)
	                sprintf(desloc,"0%d(SP)",p->desloc);
                else
                    sprintf(desloc,"%d(SP)",p->desloc);
                
                attribute->local=desloc;
                attribute->type=p->type;
                yyval.no = create_leaf(0, idf_node, yystack.l_mark[0].cadeia, attribute); 
            }
break;
case 25:
#line 317 "pico.y"
	{
                entry_t* p = lookup(symbol_table, yystack.l_mark[-3].cadeia) ;
                if(p==NULL)
                {
                    yyerror("Identificador invalido [array].");
                    exit(-1);
                }

                Attr*  attribute = (Attr*) malloc(sizeof(Attr));
                char* desloc = malloc(sizeof(char)*(10));


                attribute->code=yystack.l_mark[-1].no->attribute->code;
                attribute->type=p->type;
                attribute->local=novo_tmp(TYPE_INT);

                
                append_inst_tac(&attribute->code, create_inst_tac(TAC_EXPR, attribute->local, "0","", ""));                 
                
                char* temp=(char*)malloc(sizeof(char)*16);
                char* aux=(char*)malloc(sizeof(char)*16);

                temp=novo_tmp(TYPE_INT);
                
                Node*  node_aux = yystack.l_mark[-1].no;
                
                struct array_info* arr = p->extra;
                while(arr!=NULL)
                {
                    sprintf(aux,"%d",arr->off);
                    append_inst_tac(&attribute->code, create_inst_tac(TAC_EXPR, temp, aux,"MUL", node_aux->attribute->local));                 
                    append_inst_tac(&attribute->code, create_inst_tac(TAC_EXPR, attribute->local, attribute->local,"ADD", temp));                 
                    arr=arr->next;
                    if(node_aux->children!=NULL)
                        node_aux=node_aux->children[2];
                }                
                
                sprintf(aux,"%d",p->extra->offset);
                append_inst_tac(&attribute->code, create_inst_tac(TAC_EXPR, attribute->local, attribute->local,"SUB", aux));                 
       
                if(p->type==TYPE_INT)
                    sprintf(aux,"%d",4);
                else if(p->type==TYPE_INT)
                    sprintf(aux,"%d",1);
                else
                    sprintf(aux,"%d",8);
               
                append_inst_tac(&attribute->code, create_inst_tac(TAC_EXPR, attribute->local, attribute->local,"MUL", aux));                 
                               
                if(p->desloc<10)
                    sprintf(temp,"%s(00%d(SP))",attribute->local,p->desloc);
                else if(p->desloc<100)
                    sprintf(temp,"%s(0%d(SP))",attribute->local,p->desloc);
                else
                    sprintf(temp,"%s(%d(SP))",attribute->local,p->desloc);
                
                
                attribute->local=temp;   
                                        
                Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                children[0]=create_leaf(0, idf_node, yystack.l_mark[-3].cadeia, NULL);
                children[1]=create_leaf(0, '[', "[", NULL);
                children[2]=yystack.l_mark[-1].no;
                children[3]=create_leaf(0, ']', "]", NULL);
                yyval.no=create_node(0, lvalue_node, "__lvalue", attribute, 4, children);
            }
break;
case 26:
#line 385 "pico.y"
	{ yyval.no=yystack.l_mark[0].no; }
break;
case 27:
#line 387 "pico.y"
	{
                        Attr*  attribute = (Attr*) malloc(sizeof(Attr));
                        attribute->local=yystack.l_mark[-2].no->attribute->local;
                        attribute->code=yystack.l_mark[-2].no->attribute->code;
                        cat_tac(&attribute->code, &yystack.l_mark[0].no->attribute->code);
                        
                        Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                        children[0]=yystack.l_mark[-2].no;
                        children[1]=create_leaf(0, ',', ",", NULL);
                        children[2]=yystack.l_mark[0].no;
                        yyval.no=create_node(0, listaexpr_node, "__listaexpr", attribute, 3, children);
            }
break;
case 28:
#line 402 "pico.y"
	{          
                                     
                        Attr*  attribute = (Attr*) malloc(sizeof(Attr));


                        struct node_tac*  nodetac=NULL;
                        struct tac*  new_tac = NULL;

                        if(yystack.l_mark[-2].no->attribute->type==0 || yystack.l_mark[0].no->attribute->type==0 || yystack.l_mark[-2].no->attribute->type==TYPE_CHAR || yystack.l_mark[0].no->attribute->type==TYPE_CHAR)
                        {
                            yyerror("Tipo invalido.");
                            exit(-1);                            
                        }
                        if(yystack.l_mark[-2].no->attribute->type==TYPE_INT && yystack.l_mark[0].no->attribute->type==TYPE_INT)
                        {
                            attribute->type=TYPE_INT;
                            attribute->local=novo_tmp(TYPE_INT);
                            new_tac=create_inst_tac(TAC_EXPR,attribute->local, yystack.l_mark[-2].no->attribute->local,"ADD", yystack.l_mark[0].no->attribute->local);
                        }
                        else
                        {
                            if(yystack.l_mark[-2].no->attribute->type==TYPE_DOUBLE || yystack.l_mark[0].no->attribute->type==TYPE_DOUBLE)
                            {
                                attribute->type=TYPE_DOUBLE;
                                attribute->local=novo_tmp(TYPE_DOUBLE);
                            }
                            else
                            {
                                attribute->type=TYPE_REAL;
                                attribute->local=novo_tmp(TYPE_REAL);
                            }
                            new_tac=create_inst_tac(TAC_EXPR,attribute->local, yystack.l_mark[-2].no->attribute->local,"FADD", yystack.l_mark[0].no->attribute->local);
                        }
                        
                        cat_tac(&nodetac, &yystack.l_mark[-2].no->attribute->code);
                        cat_tac(&nodetac, &yystack.l_mark[0].no->attribute->code);
                        append_inst_tac(&nodetac, new_tac); 
                        
                        attribute->code=nodetac;

                        Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                        children[0]=yystack.l_mark[-2].no;
                        children[1]=create_leaf(0, '+', "+", NULL);
                        children[2]=yystack.l_mark[0].no;
                        yyval.no=create_node(0, plus_node, "__lvalue", attribute, 3, children);
            }
break;
case 29:
#line 449 "pico.y"
	{
                        Attr*  attribute = (Attr*) malloc(sizeof(Attr));

                        struct node_tac*  nodetac=NULL;
                        struct tac*  new_tac = NULL;

                        if(yystack.l_mark[-2].no->attribute->type==0 || yystack.l_mark[0].no->attribute->type==0 || yystack.l_mark[-2].no->attribute->type==TYPE_CHAR || yystack.l_mark[0].no->attribute->type==TYPE_CHAR)
                        {
                            yyerror("Tipo invalido.");
                            exit(-1);                            
                        }
                        if(yystack.l_mark[-2].no->attribute->type==TYPE_INT && yystack.l_mark[0].no->attribute->type==TYPE_INT)
                        {
                            attribute->type=TYPE_INT;
                            attribute->local=novo_tmp(TYPE_INT);
                            new_tac=create_inst_tac(TAC_EXPR,attribute->local, yystack.l_mark[-2].no->attribute->local,"SUB", yystack.l_mark[0].no->attribute->local);
                        }
                        else
                        {
                            if(yystack.l_mark[-2].no->attribute->type==TYPE_DOUBLE || yystack.l_mark[0].no->attribute->type==TYPE_DOUBLE)
                            {
                                attribute->type=TYPE_DOUBLE;
                                attribute->local=novo_tmp(TYPE_DOUBLE);
                            }
                            else
                            {
                                attribute->type=TYPE_REAL;
                                attribute->local=novo_tmp(TYPE_REAL);
                            }
                            new_tac=create_inst_tac(TAC_EXPR,attribute->local, yystack.l_mark[-2].no->attribute->local,"FSUB", yystack.l_mark[0].no->attribute->local);
                        }

                        cat_tac(&nodetac, &yystack.l_mark[-2].no->attribute->code);
                        cat_tac(&nodetac, &yystack.l_mark[0].no->attribute->code);
                        append_inst_tac(&nodetac, new_tac); 
                        
                        attribute->code=nodetac;

                        Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                        children[0]=yystack.l_mark[-2].no;
                        children[1]=create_leaf(0, '-', "-", NULL);
                        children[2]=yystack.l_mark[0].no;
                        yyval.no=create_node(0, minus_node, "__lvalue", attribute, 3, children);
            }
break;
case 30:
#line 494 "pico.y"
	{
                        Attr*  attribute = (Attr*) malloc(sizeof(Attr));

                        struct node_tac*  nodetac=NULL;
                        struct tac*  new_tac = NULL;

                        if(yystack.l_mark[-2].no->attribute->type==0 || yystack.l_mark[0].no->attribute->type==0 || yystack.l_mark[-2].no->attribute->type==TYPE_CHAR || yystack.l_mark[0].no->attribute->type==TYPE_CHAR)
                        {
                            yyerror("Tipo invalido.");
                            exit(-1);                            
                        }
                        if(yystack.l_mark[-2].no->attribute->type==TYPE_INT && yystack.l_mark[0].no->attribute->type==TYPE_INT)
                        {
                            attribute->type=TYPE_INT;
                            attribute->local=novo_tmp(TYPE_INT);
                            new_tac=create_inst_tac(TAC_EXPR,attribute->local, yystack.l_mark[-2].no->attribute->local,"MUL", yystack.l_mark[0].no->attribute->local);
                        }
                        else
                        {
                            if(yystack.l_mark[-2].no->attribute->type==TYPE_DOUBLE || yystack.l_mark[0].no->attribute->type==TYPE_DOUBLE)
                            {
                                attribute->type=TYPE_DOUBLE;
                                attribute->local=novo_tmp(TYPE_DOUBLE);
                            }
                            else
                            {
                                attribute->type=TYPE_REAL;
                                attribute->local=novo_tmp(TYPE_REAL);
                            }
                            new_tac=create_inst_tac(TAC_EXPR,attribute->local, yystack.l_mark[-2].no->attribute->local,"FMUL", yystack.l_mark[0].no->attribute->local);
                        }

                        cat_tac(&nodetac, &yystack.l_mark[-2].no->attribute->code);
                        cat_tac(&nodetac, &yystack.l_mark[0].no->attribute->code);
                        append_inst_tac(&nodetac, new_tac); 
                        
                        attribute->code=nodetac;

                        Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                        children[0]=yystack.l_mark[-2].no;
                        children[1]=create_leaf(0, '*', "*", NULL);
                        children[2]=yystack.l_mark[0].no;
                        yyval.no=create_node(0, mult_node, "__lvalue", attribute, 3, children);

            }
break;
case 31:
#line 540 "pico.y"
	{
                        Attr*  attribute = (Attr*) malloc(sizeof(Attr));

                        struct node_tac*  nodetac=NULL;
                        struct tac*  new_tac = NULL;
                        
                        if(yystack.l_mark[-2].no->attribute->type==0 || yystack.l_mark[0].no->attribute->type==0 || yystack.l_mark[-2].no->attribute->type==TYPE_CHAR || yystack.l_mark[0].no->attribute->type==TYPE_CHAR)
                        {
                            yyerror("Tipo invalido.");
                            exit(-1);                            
                        }
                        if(yystack.l_mark[-2].no->attribute->type==TYPE_INT && yystack.l_mark[0].no->attribute->type==TYPE_INT)
                        {
                            attribute->type=TYPE_INT;
                            attribute->local=novo_tmp(TYPE_INT);
                            new_tac=create_inst_tac(TAC_EXPR,attribute->local, yystack.l_mark[-2].no->attribute->local,"DIV", yystack.l_mark[0].no->attribute->local);
                        }
                        else
                        {
                            if(yystack.l_mark[-2].no->attribute->type==TYPE_DOUBLE || yystack.l_mark[0].no->attribute->type==TYPE_DOUBLE)
                            {
                                attribute->type=TYPE_DOUBLE;
                                attribute->local=novo_tmp(TYPE_DOUBLE);
                            }
                            else
                            {
                                attribute->type=TYPE_REAL;
                                attribute->local=novo_tmp(TYPE_REAL);
                            }
                            new_tac=create_inst_tac(TAC_EXPR,attribute->local, yystack.l_mark[-2].no->attribute->local,"FDIV", yystack.l_mark[0].no->attribute->local);
                        }

                        cat_tac(&nodetac, &yystack.l_mark[-2].no->attribute->code);
                        cat_tac(&nodetac, &yystack.l_mark[0].no->attribute->code);
                        append_inst_tac(&nodetac, new_tac); 
                        
                        attribute->code=nodetac;

                        Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                        children[0]=yystack.l_mark[-2].no;
                        children[1]=create_leaf(0, '/', "/", NULL);
                        children[2]=yystack.l_mark[0].no;
                        yyval.no=create_node(0, div_node, "__lvalue", attribute, 3, children);
            }
break;
case 32:
#line 585 "pico.y"
	{ 
                        
                        Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                        children[0]=create_leaf(0, '(', "(", NULL);
                        children[1]=yystack.l_mark[-1].no;
                        children[2]=create_leaf(0, ')', ")", NULL);
                        yyval.no=create_node(0, expr_node, "__lvalue", yystack.l_mark[-1].no->attribute, 3, children);
            }
break;
case 33:
#line 594 "pico.y"
	{ 
                        Attr*  attribute = (Attr*) malloc(sizeof(Attr));
                        attribute->local=yystack.l_mark[0].cadeia;
                        attribute->code=NULL;
                        attribute->type=TYPE_INT;
                        yyval.no = create_leaf(0, int_node, yystack.l_mark[0].cadeia, attribute); 
            }
break;
case 34:
#line 602 "pico.y"
	{ 
                        Attr*  attribute = (Attr*) malloc(sizeof(Attr));
                        attribute->local=yystack.l_mark[0].cadeia;
                        attribute->code=NULL;
                        attribute->type=TYPE_DOUBLE;
                        yyval.no = create_leaf(0, float_node, yystack.l_mark[0].cadeia, attribute); 
            }
break;
case 35:
#line 610 "pico.y"
	{ 
                yyval.no = yystack.l_mark[0].no; 
            }
break;
case 36:
#line 613 "pico.y"
	{ yyval.no = yystack.l_mark[0].no; }
break;
case 37:
#line 617 "pico.y"
	{

                Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                children[0]=create_leaf(0, idf_node, yystack.l_mark[-3].cadeia, NULL);
                children[1]=create_leaf(0, '(', "(", NULL);
                children[2]=yystack.l_mark[-1].no;
                children[3]=create_leaf(0, ')', ")", NULL);
                yyval.no=create_node(0, call_proc_node, "__chamaproc", NULL, 4, children);
            }
break;
case 38:
#line 628 "pico.y"
	{ yyval.no = yystack.l_mark[0].no ;}
break;
case 39:
#line 630 "pico.y"
	{
            
                Attr*  attribute = (Attr*) malloc(sizeof(Attr));
              
                attribute->next=novo_rot(malloc(sizeof(char)*(10)));                
                
                /*S → if { B.t := novo_rot; B.f:=novo_rot; }*/

                yystack.l_mark[-4].no->attribute->t=novo_rot(malloc(sizeof(char)*(10)));

                if(yystack.l_mark[0].no->type==fim_ctrl_node)
                    yystack.l_mark[-4].no->attribute->f=novo_rot(malloc(sizeof(char)*(10)));
                else
                    yystack.l_mark[-4].no->attribute->f=attribute->next;
                    

                /*B then { S1.next := S.next;}*/
                
                yystack.l_mark[-1].no->attribute->next=attribute->next;
   
                /*S1 else {S2.next:=S.next;}*/
                
                if(yystack.l_mark[0].no->attribute!=NULL)
                    yystack.l_mark[0].no->attribute->next=attribute->next;

                /* percorre nodo expool herdando os atributos de do nodo pai - IF*/
                gen_attributes_exbool(yystack.l_mark[-4].no);
                /* agora jah eh possível sintetizar os atributos*/

                /*S2 {S.code:=B.code ||                */
                attribute->code=yystack.l_mark[-4].no->attribute->code;
                
                /*geracod (B.t':')||                */
                struct tac* new_tac1 = create_inst_tac(TAC_LABEL,"", yystack.l_mark[-4].no->attribute->t,"", "");
                append_inst_tac(&attribute->code, new_tac1);
                
                /*S1.code ||*/
                cat_tac(&attribute->code, &yystack.l_mark[-1].no->attribute->code);

                if(yystack.l_mark[0].no->type==fim_ctrl_node)
                {                
                    /*geracod('goto' S.next) ||*/
                    struct tac* new_tac2 = create_inst_tac(TAC_GOTO,"", attribute->next,"", "");
                    append_inst_tac(&attribute->code, new_tac2); 

                    /*geracod(B.f':')||*/
                    struct tac* new_tac3 = create_inst_tac(TAC_LABEL,"", yystack.l_mark[-4].no->attribute->f,"", "");
                    append_inst_tac(&attribute->code, new_tac3);
                    
                    /*S2.code || */
                    cat_tac(&attribute->code, &yystack.l_mark[0].no->attribute->code);
                
                }

                
                /*geracod(S.next ':') }*/
                struct tac* new_tac4 = create_inst_tac(TAC_LABEL,"", attribute->next,"", "");
                append_inst_tac(&attribute->code, new_tac4); 
               
           
                Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                children[0]=create_leaf(0, if_kw_node, "if", NULL);
                children[1]=create_leaf(0, '(', "(", NULL);
                children[2]=yystack.l_mark[-4].no;
                children[3]=create_leaf(0, ')', ")", NULL);
                children[4]=create_leaf(0, then_kw_node, "then", NULL);
                children[5]=yystack.l_mark[-1].no;
                children[6]=yystack.l_mark[0].no;

                yyval.no=create_node(0, if_node, "__enuciado", attribute, 7, children);
            }
break;
case 40:
#line 702 "pico.y"
	{ 
                Attr*  attribute = (Attr*) malloc(sizeof(Attr));
              
                attribute->next=novo_rot(malloc(sizeof(char)*(10)));   

                /*S → while {B.f := S.next;*/
                yystack.l_mark[-4].no->attribute->f=attribute->next;
                
                /*B.t := novo_rot;}*/
                yystack.l_mark[-4].no->attribute->t=novo_rot(malloc(sizeof(char)*(10)));
                
                /*B do*/
                /*S1 { S.begin := novo_rot;*/
                attribute->begin=novo_rot(malloc(sizeof(char)*(10)));   

                /* percorre nodo expool herdando os atributos de do nodo pai - while*/
                gen_attributes_exbool(yystack.l_mark[-4].no);
                /* agora jah eh possível sintetizar os atributos*/

                /*geracod (S.begin ':') ||*/
                struct tac* new_tac1 = create_inst_tac(TAC_LABEL,"", attribute->begin,"", "");
                append_inst_tac(&attribute->code, new_tac1);
                
                /*B.code ||*/
                cat_tac(&attribute->code, &yystack.l_mark[-4].no->attribute->code);
                
                /*geracod(B.t: ) ||*/
                struct tac* new_tac2 = create_inst_tac(TAC_LABEL,"",yystack.l_mark[-4].no->attribute->t,"", "");
                append_inst_tac(&attribute->code, new_tac2);
                
                /*S1.code ||*/
                cat_tac(&attribute->code, &yystack.l_mark[-1].no->attribute->code);
                               
                /*geracod('goto' S.begin) || geracod( S.next ':') }*/
                struct tac* new_tac3 = create_inst_tac(TAC_GOTO,"",attribute->begin,"", "");
                append_inst_tac(&attribute->code, new_tac3);

                struct tac* new_tac4 = create_inst_tac(TAC_LABEL,"",attribute->next,"", "");
                append_inst_tac(&attribute->code, new_tac4);

                       
            
                Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                children[0]=create_leaf(0, while_kw_node, "while", NULL);
                children[1]=create_leaf(0, '(', "(", NULL);
                children[2]=yystack.l_mark[-4].no;
                children[3]=create_leaf(0, ')', ")", NULL);
                children[4]=create_leaf(0, '{', "{", NULL);
                children[5]=yystack.l_mark[-1].no;
                children[6]=create_leaf(0, '}', "}", NULL);
                yyval.no=create_node(0, while_node, "__enunciado", attribute, 7, children);
            }
break;
case 41:
#line 755 "pico.y"
	{               Attr*  attribute = (Attr*) malloc(sizeof(Attr));

                        

                        cat_tac(&attribute->code, &yystack.l_mark[-1].no->attribute->code);
                        append_inst_tac(&attribute->code, create_inst_tac(TAC_PRINT,"",yystack.l_mark[-1].no->attribute->local,"", "")); 
                        
    
                        Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                        children[0]=create_leaf(0, 'i', "print", NULL);
                        children[1]=create_leaf(0, '(', "(", NULL);
                        children[2]=yystack.l_mark[-1].no;
                        children[3]=create_leaf(0, ')', ")", NULL);
                        yyval.no=create_node(0, print_kw_node, "__lvalue", attribute, 4, children);               
            }
break;
case 42:
#line 774 "pico.y"
	{ yyval.no = create_leaf(0, end_node, "end", NULL); }
break;
case 43:
#line 776 "pico.y"
	{
                
                Attr*  attribute = (Attr*) malloc(sizeof(Attr));

                attribute->code=yystack.l_mark[-1].no->attribute->code;
                
                Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                children[0]=create_leaf(0, else_node, "else", NULL);
                children[1]=yystack.l_mark[-1].no;
                children[2]=create_leaf(0, end_node, "end", NULL);
                yyval.no=create_node(0, fim_ctrl_node, "__fiminstcontrole", attribute, 3, children);
            }
break;
case 44:
#line 791 "pico.y"
	{  
                Attr*  attribute = (Attr*) malloc(sizeof(Attr));
                yyval.no = create_leaf(0, true_node, "true", attribute); 
            
            }
break;
case 45:
#line 797 "pico.y"
	{ 

                Attr*  attribute = (Attr*) malloc(sizeof(Attr));
                yyval.no = create_leaf(0, false_node, "false", attribute); 
              
            }
break;
case 46:
#line 804 "pico.y"
	{ 
                Attr*  attribute = (Attr*) malloc(sizeof(Attr));

                Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                children[0]=create_leaf(0, '(', "(", NULL);
                children[1]=yystack.l_mark[-1].no;
                children[2]=create_leaf(0, ')', ")", NULL);
                yyval.no=create_node(0, assexpbool_node, "__expbool", attribute, 3, children);
            }
break;
case 47:
#line 814 "pico.y"
	{
                Attr*  attribute = (Attr*) malloc(sizeof(Attr));
                
                Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                children[0]=yystack.l_mark[-2].no;
                children[1]=create_leaf(0, and_kw_node, "&&", NULL);
                children[2]=yystack.l_mark[0].no;
                yyval.no=create_node(0, and_node, "__expbool", attribute, 3, children);
            }
break;
case 48:
#line 824 "pico.y"
	{
                Attr*  attribute = (Attr*) malloc(sizeof(Attr));
                
                Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                children[0]=yystack.l_mark[-2].no;
                children[1]=create_leaf(0, or_kw_node, "||", NULL);
                children[2]=yystack.l_mark[0].no;
                yyval.no=create_node(0, or_node, "__expbool", attribute, 3, children);
            }
break;
case 49:
#line 834 "pico.y"
	{
                Attr*  attribute = (Attr*) malloc(sizeof(Attr));
                            
                Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                children[0]=create_leaf(0, not_kw_node, "!", NULL);
                children[1]=yystack.l_mark[0].no;
                yyval.no=create_node(0, not_node, "__expbool", attribute, 2, children); 
            }
break;
case 50:
#line 843 "pico.y"
	{
                Attr*  attribute = (Attr*) malloc(sizeof(Attr));

                Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                children[0]=yystack.l_mark[-2].no;
                children[1]=create_leaf(0, '>', ">", NULL);
                children[2]=yystack.l_mark[0].no;
                yyval.no=create_node(0, relop_node, "__expbool", attribute, 3, children);

            }
break;
case 51:
#line 854 "pico.y"
	{
                Attr*  attribute = (Attr*) malloc(sizeof(Attr));

                Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                children[0]=yystack.l_mark[-2].no;
                children[1]=create_leaf(0, '<', "<", NULL);
                children[2]=yystack.l_mark[0].no;
                yyval.no=create_node(0, relop_node, "__expbool", attribute, 3, children);

            }
break;
case 52:
#line 865 "pico.y"
	{
                Attr*  attribute = (Attr*) malloc(sizeof(Attr));

                Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                children[0]=yystack.l_mark[-2].no;
                children[1]=create_leaf(0, inf_eq_node, "<=", NULL);
                children[2]=yystack.l_mark[0].no;
                yyval.no=create_node(0, relop_node, "__expbool", attribute, 3, children);
            }
break;
case 53:
#line 875 "pico.y"
	{
                Attr*  attribute = (Attr*) malloc(sizeof(Attr));

                Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                children[0]=yystack.l_mark[-2].no;
                children[1]=create_leaf(0, sup_eq_node, ">=", NULL);
                children[2]=yystack.l_mark[0].no;
                yyval.no=create_node(0, relop_node, "__expbool", attribute, 3, children);
            }
break;
case 54:
#line 885 "pico.y"
	{
                Attr*  attribute = (Attr*) malloc(sizeof(Attr));

                Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                children[0]=yystack.l_mark[-2].no;
                children[1]=create_leaf(0, eq_node, "=", NULL);
                children[2]=yystack.l_mark[0].no;
                yyval.no=create_node(0, relop_node, "__expbool", attribute, 3, children);
            }
break;
case 55:
#line 895 "pico.y"
	{
                Attr*  attribute = (Attr*) malloc(sizeof(Attr));

                Node**  children = (Node**) malloc(MAX_CHILDREN_NUMBER*sizeof(Node*));
                children[0]=yystack.l_mark[-2].no;
                children[1]=create_leaf(0, neq_node, "!=", NULL);
                children[2]=yystack.l_mark[0].no;
                yyval.no=create_node(0, relop_node, "__expbool", attribute, 3, children);
            }
break;
#line 1707 "y.tab.c"
    }
    yystack.s_mark -= yym;
    yystate = *yystack.s_mark;
    yystack.l_mark -= yym;
    yym = yylhs[yyn];
    if (yystate == 0 && yym == 0)
    {
#if YYDEBUG
        if (yydebug)
            printf("%sdebug: after reduction, shifting from state 0 to\
 state %d\n", YYPREFIX, YYFINAL);
#endif
        yystate = YYFINAL;
        *++yystack.s_mark = YYFINAL;
        *++yystack.l_mark = yyval;
        if (yychar < 0)
        {
            if ((yychar = YYLEX) < 0) yychar = 0;
#if YYDEBUG
            if (yydebug)
            {
                yys = 0;
                if (yychar <= YYMAXTOKEN) yys = yyname[yychar];
                if (!yys) yys = "illegal-symbol";
                printf("%sdebug: state %d, reading %d (%s)\n",
                        YYPREFIX, YYFINAL, yychar, yys);
            }
#endif
        }
        if (yychar == 0) goto yyaccept;
        goto yyloop;
    }
    if ((yyn = yygindex[yym]) && (yyn += yystate) >= 0 &&
            yyn <= YYTABLESIZE && yycheck[yyn] == yystate)
        yystate = yytable[yyn];
    else
        yystate = yydgoto[yym];
#if YYDEBUG
    if (yydebug)
        printf("%sdebug: after reduction, shifting from state %d \
to state %d\n", YYPREFIX, *yystack.s_mark, yystate);
#endif
    if (yystack.s_mark >= yystack.s_last && yygrowstack(&yystack))
    {
        goto yyoverflow;
    }
    *++yystack.s_mark = (short) yystate;
    *++yystack.l_mark = yyval;
    goto yyloop;

yyoverflow:
    yyerror("yacc stack overflow");

yyabort:
    yyfreestack(&yystack);
    return (1);

yyaccept:
    yyfreestack(&yystack);
    return (0);
}
